package banking;


import formatter.FormFactory;
import interfaces.BankRegistry;
import interfaces.UserInterface;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;

import money.Money;
import clockwork.Clockwork;

	public class BankImpl implements UserInterface, Observer{
	
	Properties properties = new Properties();
	public String BankName;
	Map<Integer, Account>accountMap;
	public BankImpl(String BankName){
		
		this.BankName = BankName;
		this.accountMap = new HashMap<Integer, Account>();
	}
		
	// ### add DepositAccount to Array ###
	public void newDepositAccount(int accountNumber, String accountNameDep, int runtime,
			String language, String country) {
		
		Account account = new DepositAccount(accountNumber, accountNameDep, 
				"Deposite Konto", language, country);
		account.depcon.setInterest(runtime);
		account.depcon.setRuntime(runtime);
		toHash(accountNumber, account);
	}

	// ### add DepositAccount to Array ###
	public void newGiroAccount(int accountNumber, String accountNameGiro, int creditrating,
			String language, String country) {
		
		Account account = new DepositAccount(accountNumber, accountNameGiro,
				"Deposite Konto", language, country);
		account.girocon.setInterest(creditrating);
		
		toHash(accountNumber, account);
	}

	//## add Object to Hash map
	public void toHash(int accountNumber, Account account){
		
		accountMap.put(accountNumber, account);
	}
	
	// ### Shows Account Value ###
	public String showAccountValue(int accountNumber) throws Exception {
		Account account = accountMap.get(accountNumber);
		return account.showOutput();
	}

	// ### Remove money from Account ###
	public void removeMoney(Money value, String reason, int accountNumber)
			throws Exception {
		Account account = accountMap.get(accountNumber);
		account.minus(value);
		createStatement(accountNumber, reason, value);
	}

	// ### Add money to Account ###
	public void addMoney(Money value, String reason, int accountNumber)
			throws Exception {
		Account account = accountMap.get(accountNumber);
		account.plus(value);
		createStatement(accountNumber, reason, value);
	}

	// ### Transfer ###
	public void transferMoney(int acceptorNumber, Money value, String reason,
			int accountNumber) throws Exception {
		// Transfer
		Account account = accountMap.get(accountNumber);
		Account acceptor = accountMap.get(acceptorNumber);
		account.minus(value);
		acceptor.plus(value);
		createStatement(accountNumber, reason, value);
		createStatement(acceptorNumber	, reason, value);
	}

	// ### Interest for every Account ###
	public void interestAll(int accountNumber) throws Exception {
		Account account = accountMap.get(accountNumber);
		account.interest();

	}

	// ### Choose Account ###
	public void chooseAccount(int newaccountNumber) throws Exception {
		Account account = accountMap.get(newaccountNumber);
		account.setAccountNumber(newaccountNumber);
	}
	
	// ### Create Statement Object ###
	public void createStatement(int accountNumber, String reason, Money value) {
		Statement statement = new Statement();
		Account account = accountMap.get(accountNumber);
		statement.setAccountNumber(accountNumber);
		statement.setReason(reason);
		statement.setValue(value.getValue());
		statement.setDate(Clockwork.getTime());
		account.getBookList().add(statement);
	}

	// ### Account Statement ###
	public String accountStatement(int accountNumber, String mimeType) throws Exception {
		Account account = accountMap.get(accountNumber);
		Collections.sort(account.getBookList(), new CompareStr());
		
		FormFactory factory = new FormFactory(account);
		//System.out.println(factory.getStatementFormatter(mimeType).getFormattedText());
		return factory.getStatementFormatter(mimeType).getFormattedText();
	}
	
	// ### Transfer Bank2Bank
	public void transferB2B(int myBankNumber, int acceptorNumber, String BankName, 
			Money value, String reason) throws Exception {
		if(BankRegistry.loockup(BankName) != null){
			removeMoney(value, reason, myBankNumber);
			BankRegistry.B2Btransfer(acceptorNumber, BankName, value, reason);
		}
			
	}
	
	@Override
	public void update(Observable days, Object clockwork) {
		try {
			//interestAll();
		} catch (Exception e) {
			
			e.printStackTrace();
		}
	}
	/*
	 * #####################################
	 * 			 Getter / Setter
	 * ####################################
	 */

	public Map<Integer, Account> getAccountMap() {
		return accountMap;
	}

	public void setAcstatementcountMap(Map<Integer, Account> accountMap) {
		this.accountMap = accountMap;
	}
		

	// TEST#######################################################

}
